#ifndef _PROJECT1_MYFUNCTIONS_
#define _PROJECT1_MYFUNCTIONS_

#include "Core/Vec.h"

enum {Dim = 2};
using rVec = Vec<Real, Dim>;
using iVec = Vec<int, Dim>;


Real SINCOS(const rVec &x)
{
   return sin(4*M_PI*x[0]) * cos(3*M_PI*x[1]);
}

rVec DSINCOS(const rVec &x)
{
  return rVec{
      4 * M_PI * cos(4 * M_PI * x[0]) * cos(3 * M_PI * x[1]),
      -3 * M_PI * sin(4 * M_PI * x[0]) * sin(3 * M_PI * x[1])};
}

Real negDDSINCOS(const rVec &x)
{
  return 25 * M_PI * M_PI * sin(4 * M_PI * x[0]) * cos(3 * M_PI * x[1]);
}

Real BETA(const rVec &x)
{
  return 1.0 + x[0] + x[1];
}

rVec DBETA(const rVec &x)
{
  return rVec{1.0, 1.0};
}

Real negDDBETA(const rVec &x)
{
  return 0;
}

Real EXPT1(const rVec &x)
{
  return exp(sin(x[0])+x[1]);
}

rVec DEXPT1(const rVec &x)
{
  return rVec{cos(x[0])*exp(sin(x[0])+x[1]), exp(sin(x[0])+x[1])};
}

Real negDDEXPT1(const rVec &x)
{
  return -exp(sin(x[0])+x[1])*(1.0+cos(x[0])*cos(x[0])-sin(x[0]));
}

Real negDDEXPT2(const rVec &x)
{
  return -2.0*x[0]*x[0]-2.0*x[1]*x[1];
}

Real EXPT2(const rVec &x)
{
  return x[0]*x[0]*x[1]*x[1];
}

rVec DEXPT2(const rVec &x)
{
  return rVec{2.0*x[0]*x[1]*x[1],2.0*x[1]*x[0]*x[0]};
}

#endif // !_PROJECT1_MYFUNCTIONS_